package com.gitee.wsl.collections.iterator

import com.gitee.wsl.base.Objects


/**
 * An Iterator that restarts when it reaches the end.
 *
 *
 * The iterator will loop continuously around the provided elements, unless
 * there are no elements in the collection to begin with, or all the elements
 * have been [removed][.remove].
 *
 *
 *
 * Concurrent modifications are not directly supported, and for most collection
 * implementations will throw a ConcurrentModificationException.
 *
 *
 * @param <E> the type of elements returned by this iterator.
 * @since 3.0
</E> */
class LoopingIterator<E>(private val collection: Collection< E>) : Iterator<E> {
    /** The collection to base the iterator on  */
    //private val collection: Collection<E>

    /** The current iterator  */
    private lateinit var iterator: Iterator<E>



    /**
     * Constructor that wraps a collection.
     *
     *
     * There is no way to reset an Iterator instance without recreating it from
     * the original source, so the Collection must be passed in.
     *
     *
     * @param collection  the collection to wrap
     * @throws NullPointerException if the collection is null
     */
    init {
        //this.collection = Objects.requireNonNull(collection, "collection")
        reset()
    }

    /**
     * Has the iterator any more elements.
     *
     *
     * Returns false only if the collection originally had zero elements, or
     * all the elements have been [removed][.remove].
     *
     *
     * @return `true` if there are more elements
     */
    public override fun hasNext(): Boolean {
        return !collection.isEmpty()
    }

    /**
     * Returns the next object in the collection.
     *
     *
     * If at the end of the collection, return the first element.
     *
     *
     * @return the next object
     * @throws NoSuchElementException if there are no elements
     * at all.  Use [.hasNext] to avoid this error.
     */
    public override fun next(): E {
        if (collection.isEmpty()) {
            throw NoSuchElementException("There are no elements for this iterator to loop on")
        }
        if (!iterator.hasNext()) {
            reset()
        }
        return iterator.next()
    }

    /**
     * Removes the previously retrieved item from the underlying collection.
     *
     *
     * This feature is only supported if the underlying collection's
     * [Collection.iterator] method returns an implementation
     * that supports it.
     *
     *
     *
     * This method can only be called after at least one [.next] method call.
     * After a removal, the remove method may not be called again until another
     * next has been performed. If the [.reset] is called, then remove may
     * not be called until [.next] is called again.
     *
     */
//    public override fun remove() {
//        iterator.remove()
//    }

    /**
     * Resets the iterator back to the start of the collection.
     */
    public  fun reset() {
        iterator = collection.iterator()
    }

    /**
     * Gets the size of the collection underlying the iterator.
     *
     * @return the current collection size
     */
    fun size(): Int {
        return collection.size
    }
}
